package com.mlethe.library.recyclerview.adapter;

import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.mlethe.library.recyclerview.listener.MultiTypeSupport;
import com.mlethe.library.recyclerview.viewholder.ViewHolder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Mlethe
 * @date 2020/11/3
 */
public abstract class BaseGridPagerAdapter<T> extends BaseQuickAdapter<T> {

    /**
     * 行数
     */
    private int mRowCount = 1;

    /**
     * 列数
     */
    private int mColumnCount = 1;

    /**
     * 获取滑动一页的长度
     */
    private int mPageSize = 0;

    /**
     * 一页的左右 margin
     */
    private int mPageMargin = 0;

    public BaseGridPagerAdapter(int layoutId) {
        super(layoutId);
    }

    public BaseGridPagerAdapter(MultiTypeSupport<T> multiTypeSupport) {
        super(multiTypeSupport);
    }

    public BaseGridPagerAdapter(List<T> data, int layoutId) {
        super(data, layoutId);
    }

    public BaseGridPagerAdapter(List<T> data, MultiTypeSupport<T> multiTypeSupport) {
        super(data, multiTypeSupport);
    }

    /**
     * 设置行数
     *
     * @param row 行数
     * @return
     */
    public BaseGridPagerAdapter<T> setRow(int row) {
        if (mRowCount <= 0) {
            row = 1;
        }
        this.mRowCount = row;
        return this;
    }

    /**
     * 设置列数
     *
     * @param column 列数
     * @return
     */
    public BaseGridPagerAdapter<T> setColumn(int column) {
        if (mColumnCount <= 0) {
            column = 1;
        }
        this.mColumnCount = column;
        return this;
    }

    /**
     * 获取滑动一页的长度
     *
     * @param size px
     * @return
     */
    public BaseGridPagerAdapter<T> setPageSize(int size) {
        this.mPageSize = size;
        return this;
    }

    /**
     * 一页的左右 margin
     *
     * @param size px
     * @return
     */
    public BaseGridPagerAdapter<T> setPageMargin(int size) {
        this.mPageMargin = size;
        return this;
    }

    @Override
    protected final void convert(@NonNull ViewHolder holder, T item, int position) {
        int remainder = 0;
        if (mPageSize > 0) {
            ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) holder.itemView.getLayoutParams();
            if (RecyclerView.VERTICAL == getOrientation()) {
                layoutParams.height = (mPageSize - mPageMargin * 2) / mRowCount;
                if (mPageMargin > 0) {
                    remainder = position / mColumnCount % mRowCount;
                    if (remainder == 0) {
                        layoutParams.topMargin = mPageMargin;
                        layoutParams.bottomMargin = 0;
                    } else if (remainder == mRowCount - 1) {
                        layoutParams.topMargin = 0;
                        layoutParams.bottomMargin = mPageMargin;
                    } else {
                        layoutParams.topMargin = 0;
                        layoutParams.bottomMargin = 0;
                    }
                }
            } else {
                layoutParams.width = (mPageSize - mPageMargin * 2) / mColumnCount;
                if (mPageMargin > 0) {
                    remainder = position / mRowCount % mColumnCount;
                    if (remainder == 0) {
                        layoutParams.leftMargin = mPageMargin;
                        layoutParams.rightMargin = 0;
                    } else if (remainder == mColumnCount - 1) {
                        layoutParams.leftMargin = 0;
                        layoutParams.rightMargin = mPageMargin;
                    } else {
                        layoutParams.leftMargin = 0;
                        layoutParams.rightMargin = 0;
                    }
                }
            }
            holder.itemView.setLayoutParams(layoutParams);
        }
        convert(holder, item, position, remainder);
    }

    @Override
    protected final void convert(@NonNull ViewHolder holder, T item, int position, @NonNull List<Object> payloads) {
        int remainder = 0;
        if (mPageSize > 0) {
            ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) holder.itemView.getLayoutParams();
            if (RecyclerView.VERTICAL == getOrientation()) {
                layoutParams.height = (mPageSize - mPageMargin * 2) / mRowCount;
                if (mPageMargin > 0) {
                    remainder = position / mColumnCount % mRowCount;
                    if (remainder == 0) {
                        layoutParams.topMargin = mPageMargin;
                        layoutParams.bottomMargin = 0;
                    } else if (remainder == mRowCount - 1) {
                        layoutParams.topMargin = 0;
                        layoutParams.bottomMargin = mPageMargin;
                    } else {
                        layoutParams.topMargin = 0;
                        layoutParams.bottomMargin = 0;
                    }
                }
            } else {
                layoutParams.width = (mPageSize - mPageMargin * 2) / mColumnCount;
                if (mPageMargin > 0) {
                    remainder = position / mRowCount % mColumnCount;
                    if (remainder == 0) {
                        layoutParams.leftMargin = mPageMargin;
                        layoutParams.rightMargin = 0;
                    } else if (remainder == mColumnCount - 1) {
                        layoutParams.leftMargin = 0;
                        layoutParams.rightMargin = mPageMargin;
                    } else {
                        layoutParams.leftMargin = 0;
                        layoutParams.rightMargin = 0;
                    }
                }
            }
            holder.itemView.setLayoutParams(layoutParams);
        }
        convert(holder, item, position, payloads, remainder);
    }

    /**
     * 实现数据绑定
     *
     * @param holder
     * @param item
     * @param position
     * @param remainder item 当前页的行数/列数
     */
    protected abstract void convert(@NonNull ViewHolder holder, T item, int position, int remainder);

    /**
     * 实现数据绑定
     *
     * @param holder
     * @param item
     * @param position
     * @param payloads
     * @param remainder item 当前页的行数/列数
     */
    protected void convert(@NonNull ViewHolder holder, T item, int position, @NonNull List<Object> payloads, int remainder) {
    }

    /**
     * 新数据设置
     *
     * @param list
     * @return
     */
    public final void setDataFillEmpty(List<T> list) {
        List<T> data = getData();
        if (data != null && data.size() > 0) {
            data.removeAll(Collections.singleton(null));
        }
        setData(transform(list));
    }

    /**
     * 新数据设置并更新
     *
     * @param list
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean setNewDataFillEmpty(List<T> list) {
        return setNewData(transform(list));
    }

    /**
     * 格式化数据
     *
     * @param dataList
     * @return
     */
    public List<T> transform(List<T> dataList) {
        if (dataList == null || dataList.isEmpty()) {
            return null;
        }
        List<T> destList = new ArrayList<T>();

        int pageSize = mRowCount * mColumnCount;
        int size = dataList.size();

        int afterTransformSize;
        if (size < pageSize) {
            afterTransformSize = pageSize;
        } else if (size % pageSize == 0) {
            afterTransformSize = size;
        } else {
            afterTransformSize = (size / pageSize + 1) * pageSize;
        }

        int orientation = getOrientation();

        for (int i = 0; i < afterTransformSize; i++) {
            if (orientation == RecyclerView.VERTICAL) {
                if (i < size) {
                    destList.add(dataList.get(i));
                } else {
                    destList.add(null);
                }
            } else {
                int index = transformIndex(i, mRowCount, mColumnCount);
                if (index >= 0 && index < size) {
                    destList.add(dataList.get(index));
                } else {
                    destList.add(null);
                }
            }
        }

        return destList;
    }

    protected int transformIndex(int index, int row, int column) {
        int pageCount = row * column;

        //current page index
        int curPageIndex = index / pageCount;
        int divisor = index % pageCount;

        int transformIndex = divisor / row + column * (divisor % row);

        //this is very important
        transformIndex += curPageIndex * pageCount;

        return transformIndex;
    }

}
